package com.h3bpm.handler;

import OThinker.Common.Data.Database.ICommand;
import OThinker.Common.Organization.Models.User;
import OThinker.H3.Entity.IEngine;
import OThinker.H3.Entity.WorkItem.CirculateModels.CirculateItem;
import OThinker.H3.Entity.WorkItem.WorkItemModels.WorkItem;
import OThinker.H3.Entity.WorkItem.WorkItemState;
import com.h3bpm.handler.Utils.DateUtil;
import com.h3bpm.handler.Utils.HttpLocalUtils;
import com.h3bpm.handler.domin.EsbReqHead;
import data.DataException;
import data.DataRow;
import data.DataTable;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 推送数据至门户
 */
public class PushToPortal {
    //生产
//    public static String ESBURL = "http://10.66.38.121:8081/esb/webservice/commRequest";
//    public static String BPMURL = "http://bpm.tongji-ec.com.cn";
    //测试
    public static String ESBURL = "http://10.66.38.122:8081/esb/webservice/commRequest";
    public static String BPMURL = "http://bpmtest.tongji-ec.com.cn";
//    public static String ecSystemName = "EC";
//    public static String portalSystemName = "Portal";
    public static String sourceSystem ="BPM";
    public static String targetSystem = "Portal";
    public static String userServiceName = "S0090001A";
    public static String unfinishedServiceName = "S0090002A";
    public static String finishedServiceName = "S0090003A";

    private static final Logger logger = LoggerFactory.getLogger(PushToPortal.class);

    /**
     *
     * @return
     */
    public static void pushItemToPortal(IEngine engine, WorkItem item, String receiver){
        String selectSql = "select * from ot_workitemfinished where ObjectID = '%s'";
        DataTable table = engine.getQuery().QueryTable(String.format(selectSql, item.getObjectID()));
        List<DataRow> entityRows = table.getEntityRows();
        if(!CollectionUtils.isEmpty(entityRows)){
            pushFinishToPortal(engine, "1", item.getWorkItemID(), receiver, item.getState(), item.getWorkflowCode());
        }else{
            //待办
            pushWorkItemToPortal(engine, item, receiver);
        }
    }

    /**
     *
     * @return
     */
    public static void pushCirculateItemToPortal(IEngine engine, CirculateItem item, String receiver){
        String selectSql = "select * from ot_circulateitemfinished where ObjectID = '%s'";
        DataTable table = engine.getQuery().QueryTable(String.format(selectSql, item.getObjectID()));
        List<DataRow> entityRows = table.getEntityRows();
        if(!CollectionUtils.isEmpty(entityRows)){
            //已阅
            pushFinishToPortal(engine, "2", item.getObjectID(), receiver, item.getState(), item.getWorkflowCode());
        }else{
            //待阅
            createCirculateItem(engine, item, receiver);
        }
    }

    /**
     * 同步推送数据至portal
     */
    public static String pushUser(IEngine engine, User item, String flag) {
        if(StringUtils.isBlank(flag)){
            return null;
        }
        String result = null;
        if(item!=null&& StringUtils.isNotBlank(item.getCode())){
            try {
                DataRow entityRow = getOrgByUserCode(engine, item.getCode());
                if(entityRow!=null){
                    Map<String, Object> map = new HashMap<>();
                    map.put("systemName", sourceSystem);
                    map.put("loginName", entityRow.getString("loginName"));
                    map.put("userNo", entityRow.getString("userNo"));
                    map.put("userName", entityRow.getString("userName"));
                    map.put("competentDept", null);
                    map.put("competentOrg", entityRow.getString("competentOrg"));
                    map.put("userStatus", entityRow.getString("userStatus"));
                    map.put("loginDate", null);
                    map.put("flag", flag);
                    String json= JSONUtils.toJson(map);
                    logger.info("同步推送数据至portal参数,json:"+json);
                    result = HttpLocalUtils.doPostToESB(ESBURL, json ,new EsbReqHead(
                            sourceSystem, targetSystem, UUID.randomUUID().toString(), userServiceName));
                    logger.info("同步推送数据至portal结果,result:"+result);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 查询用户状态是否修改，并设置flag
     * @param engine
     * @param user
     * @return
     */
    public static String getFlag(IEngine engine, User user) {
        String flag = null;
        try {
            String selectSql = "SELECT State FROM ot_user where code= '%s'";
            ICommand command = engine.getEngineConfig().getCommandFactory().CreateCommand();
            DataTable table = command.ExecuteDataTable(String.format(selectSql, user.getCode()));
            List<DataRow> entityRows = table.getEntityRows();
            if(!CollectionUtils.isEmpty(entityRows)){
                if(!ObjectUtils.nullSafeEquals(user.getCode(), entityRows.get(0).getString("State"))){
                    flag = "2";
                }
            }
        } catch (DataException e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 待办推送
     * @param engine
     * @param item
     * @return
     */
    public static void pushWorkItemToPortal(IEngine engine, WorkItem item, String receiverCode) {
        logger.info("-------进入待办推送");
        String sql = "select InstanceName,CreatedTime from ot_instancecontext where ObjectID='%s'";
        String procedureName = null;
        String initiationTime = null;
        try {
            ICommand command = engine.getEngineConfig().getCommandFactory().CreateCommand();
            DataTable table = command.ExecuteDataTable(String.format(sql, item.getInstanceID()));
            List<DataRow> entityRows = table.getEntityRows();
            if (!entityRows.isEmpty() && entityRows.size() > 0) {
                procedureName = entityRows.get(0).getString("InstanceName");
                initiationTime = DateUtil.format(entityRows.get(0).getDate("CreatedTime"));
            }
            Map<String, Object> map = new HashMap<>();
            User originator = ((User) engine.getOrganization().GetUnit(item.getOriginator()));
            DataRow entityRowOrg = getOrgByUserCode(engine, originator.getCode());
            map.put("systemName", getProcessSystem(engine, item.getWorkflowCode()));
            map.put("pendType", "1");//待办
            map.put("promoterNo", originator.getCode());
            map.put("promoter", originator.getName());
            map.put("promoterOrg", entityRowOrg!=null?entityRowOrg.getString("competentOrg"):null);
            map.put("node", item.getDisplayName());
            map.put("receiverUserCode", receiverCode);
            map.put("procedureName", getWorkflowName(engine, item.getWorkflowCode()));
            map.put("procedureNo", item.getWorkflowCode());
            map.put("title", UserHelper.splitTitle(originator.getName(), procedureName));
            map.put("sequenceNo", item.getWorkItemID());
            map.put("initiationTime", initiationTime);
            map.put("receiverTime", DateUtil.format(item.getReceiveTime()));
            map.put("pcUrl", BPMURL+UserHelper.pcAllUrl(item.getWorkflowCode(), item.getObjectID(), item.getInstanceID()));
            String json= JSONUtils.toJson(map);
            logger.info("同步推送待办数据至portal参数,json:"+json);
            String result = HttpLocalUtils.doPostToESB(ESBURL, json ,new EsbReqHead(
                    sourceSystem, targetSystem, UUID.randomUUID().toString(), unfinishedServiceName));
            logger.info("同步推送待办数据至portal结果,result:"+result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 待阅推送
     * @param engine
     * @param item
     */
    public static void createCirculateItem(IEngine engine, CirculateItem item, String receiverCode) {
        logger.info("-------进入待阅推送");
        String sql = "select InstanceName,CreatedTime from ot_instancecontext where ObjectID='%s'";
        String procedureName = null;
        String initiationTime = null;
        try {
            ICommand command = engine.getEngineConfig().getCommandFactory().CreateCommand();
            DataTable table = command.ExecuteDataTable(String.format(sql, item.getInstanceID()));
            List<DataRow> entityRows = table.getEntityRows();
            if (!entityRows.isEmpty() && entityRows.size() > 0) {
                procedureName = entityRows.get(0).getString("InstanceName");
                initiationTime = DateUtil.format(entityRows.get(0).getDate("CreatedTime"));
            }
            Map<String, Object> map = new HashMap<>();
            User originator = ((User) engine.getOrganization().GetUnit(item.getOriginator()));
            DataRow entityRowOrg = getOrgByUserCode(engine, originator.getCode());
            map.put("systemName", getProcessSystem(engine, item.getWorkflowCode()));
            map.put("pendType", "2");//待阅
            map.put("promoterNo", originator.getCode());
            map.put("promoter", originator.getName());
            map.put("promoterOrg", entityRowOrg!=null?entityRowOrg.getString("competentOrg"):null);
            map.put("node", item.getDisplayName());
            map.put("receiverUserCode", receiverCode);
            map.put("procedureName", getWorkflowName(engine, item.getWorkflowCode()));
            map.put("procedureNo", item.getWorkflowCode());
            map.put("title", UserHelper.splitTitle(originator.getName(), procedureName));
            map.put("sequenceNo", item.getObjectID());
            map.put("initiationTime", initiationTime);
            map.put("receiverTime", DateUtil.format(item.getReceiveTime()));
            map.put("pcUrl", BPMURL+UserHelper.pcAllUrl(item.getWorkflowCode(), item.getObjectID(), item.getInstanceID()));
            String json= JSONUtils.toJson(map);
            logger.info("同步推送待阅数据至portal参数,json:"+json);
            String result = HttpLocalUtils.doPostToESB(ESBURL, json ,new EsbReqHead(
                    sourceSystem, targetSystem, UUID.randomUUID().toString(), unfinishedServiceName));
            logger.info("同步推送待阅数据至portal结果,result:"+result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 已办，已阅推送
     * @param engine
     */
    public static void pushFinishToPortal(IEngine engine, String pendType, String workItemID, String receiverCode,WorkItemState workItemState,String workflowCode) {
        logger.info("-------进入已办，已阅推送");
        try {
            String status = null;
            if(WorkItemState.Canceled.equals(workItemState)){
                status = "3";
            }else{
                status = "1";
            }
            Map<String, Object> map = new HashMap<>();
            map.put("systemName", getProcessSystem(engine, workflowCode));
            map.put("pendType", pendType);
            map.put("sequenceNo", workItemID);
            map.put("receiverUserCode", receiverCode);
            map.put("status", status);
            String json= JSONUtils.toJson(map);
            logger.info("同步推送已办，已阅数据至portal参数,json:"+json);
            String result = HttpLocalUtils.doPostToESB(ESBURL, json ,new EsbReqHead(
                    sourceSystem, targetSystem, UUID.randomUUID().toString(), finishedServiceName));
            logger.info("同步推送已办，已阅数据至portal结果,result:"+result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取用户所属部门名称
     * @param engine
     */
    public static DataRow getOrgByUserCode(IEngine engine, String userCode){
        String selectSql = "SELECT null as loginName,u.name as userName, u.code as userNo,u.Extend2 as competentDept,t.name as competentOrg,\n" +
                "case when u.State='0' then '3' else u.State end as userStatus,null as loginDate \n" +
                "FROM ot_user u \n" +
                "LEFT JOIN ot_organizationunit t on u.ParentID=t.ObjectID \n" +
                "where u.code='%s'";
        DataTable table = engine.getQuery().QueryTable(String.format(selectSql, userCode));
        List<DataRow> entityRows = table.getEntityRows();
        if(!CollectionUtils.isEmpty(entityRows)){
            return entityRows.get(0);
        }
        return null;
    }

    /**
     * 获取流程所属系统
     * @param bizObjectSchemaCode
     * @return
     */
    public static String getProcessSystem(IEngine engine, String bizObjectSchemaCode){
        String system = null;
        try {
            String systemSql="select System from i_processsystem where IsDisable='否' and ProcessCode='%s'";
            DataTable systemTable = engine.getQuery().QueryTable(String.format(systemSql, bizObjectSchemaCode));
            List<DataRow> systemEntityRows = systemTable.getEntityRows();
            if(!CollectionUtils.isEmpty(systemEntityRows)){
                system = systemEntityRows.get(0).getString("System");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(StringUtils.isNotBlank(system)){
            system = system.substring(0, system.length()-1);
        }
        return system;
    }

    /**
     * 获取流程名称
     * @param workflowCode
     * @return
     */
    public static String getWorkflowName(IEngine engine, String workflowCode){
        String workflowName = null;
        try {
            String systemSql="select WorkflowName from ot_workflowclause where workflowCode='%s'";
            DataTable systemTable = engine.getQuery().QueryTable(String.format(systemSql, workflowCode));
            List<DataRow> systemEntityRows = systemTable.getEntityRows();
            if(!CollectionUtils.isEmpty(systemEntityRows)){
                workflowName = systemEntityRows.get(0).getString("WorkflowName");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return workflowName;
    }

}
